function fit = cec2013(x, func_num)
% CEC2013 F1和F15
%
% CEC2013 基准测试函数的接口：
%   f1  : Shifted Elliptic Function (移位椭圆函数)
%   f15 : Shifted Schwefel's Problem 1.2 (移位 Schwefel 1.2 函数)
%
% INPUTS:
%   x        : 决策向量，可以是列向量 (D×1) 或矩阵 (D×N)，其中 D 为维度，N 为样本数
%   func_num : 目标函数编号，只能取 1 或 15
%
% OUTPUT:
%   fit      : 对应目标函数值，返回为行向量 (1×N)

global initial_flag 

% 初始化标志变量，仅在第一次运行时设定
if (initial_flag == 0)
    initial_flag = 1;
end

% 根据函数编号调用相应的基准函数
if (func_num == 1) 
    fit = f1(x);
elseif (func_num == 15) 
    fit = f15(x);
else
    error('只支持f1和f15函数');
end

% 确保输出为行向量，避免外部调用时维度不一致
if size(fit, 1) > 1
    fit = fit';
end

end



%------------------------------------------------------------------------------
% Elliptic Function (椭圆函数)
%------------------------------------------------------------------------------
function fit = elliptic(x)
    [D, ps] = size(x);                  % D为维度，ps为样本数
    condition = 1e+6;                   % 条件数系数
    coefficients = condition .^ linspace(0, 1, D);  % 指数缩放系数 (从1到1e6)
    fit = coefficients * T_irreg(x).^2; % 应用不规则变换，再计算加权平方和
end

%------------------------------------------------------------------------------
% Schwefel's Problem 1.2 (Schwefel 1.2 函数)
%------------------------------------------------------------------------------
function fit = schwefel(x)
    [D, ps] = size(x);
    x = T_asy(T_irreg(x), 0.2);         % 先进行不规则变换 + 非对称变换
    fit = 0;
    for i = 1:D
        fit = fit + sum(x(1:i,:),1).^2; % 累积平方和
    end
end



%------------------------------------------------------------------------------
% f1: Shifted Elliptic Function
% 维度 D = 1000
% 搜索范围: [-100,100]
%------------------------------------------------------------------------------
function fit = f1(x)
    [D, ps] = size(x);
    
    % 偏移向量 (简化为零向量)
    xopt = zeros(D, 1);
    
    % 定义边界
    lb = -100 * ones(D, 1);
    ub = 100 * ones(D, 1);
    
    % 应用偏移
    x = x - repmat(xopt, 1, ps);
    
    % 计算目标函数值
    fit = elliptic(x);
    
    % 超出边界的解赋予惩罚值 (1e10)
    for i = 1:ps
        if any(x(:,i) < lb) || any(x(:,i) > ub)
            fit(i) = 1e10;
        end
    end
end

%------------------------------------------------------------------------------
% f15: Shifted Schwefel's Problem 1.2
% 维度 D = 1000
% 搜索范围: [-100,100]
%------------------------------------------------------------------------------
function fit = f15(x)
    [D, ps] = size(x);
    
    % 偏移向量 (简化为零向量)
    xopt = zeros(D, 1);
    
    % 定义边界
    lb = -100 * ones(D, 1);
    ub = 100 * ones(D, 1);
    
    % 应用偏移
    x = x - repmat(xopt, 1, ps);
    
    % 计算目标函数值
    fit = schwefel(x);
    
    % 超出边界的解赋予惩罚值 (1e10)
    for i = 1:ps
        if any(x(:,i) < lb) || any(x(:,i) > ub)
            fit(i) = 1e10;
        end
    end
end



%------------------------------------------------------------------------------
% T_asy (非对称变换)
% 作用：打破函数的对称性，使优化更困难
% beta: 控制非对称程度
%------------------------------------------------------------------------------
function g = T_asy(f, beta)
    [D, popsize] = size(f);
    g = f;
    temp = repmat(beta * linspace(0, 1, D)', 1, popsize); % 逐维权重
    ind = f > 0;
    g(ind) = f(ind).^ (1 + temp(ind) .* sqrt(f(ind)));    % 仅对正数部分变换
end

%------------------------------------------------------------------------------
% T_irreg (不规则变换)
% 作用：引入平滑局部不规则性，增加函数复杂度
%------------------------------------------------------------------------------
function g = T_irreg(f)
   a = 0.1;
   g = f; 
   % 对正数部分进行变换
   idx = (f > 0);
   g(idx) = log(f(idx))/a;
   g(idx) = exp(g(idx) + 0.49*(sin(g(idx)) + sin(0.79*g(idx)))).^a;
   % 对负数部分进行变换
   idx = (f < 0);
   g(idx) = log(-f(idx))/a;
   g(idx) = -exp(g(idx) + 0.49*(sin(0.55*g(idx)) + sin(0.31*g(idx)))).^a;
end
